package com.kilomob.grady;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kilomob.grady.concurrent.DefaultThreadFactory;

/**
 * 
 * 测试基础类
 * 
 * 
 * @author zhouzhixiang
 * @date 2016年12月24日 下午8:20:05
 * @since 1.0
 */
public abstract class ConcurrentTestBase {
    private static Logger LOGGER = LoggerFactory.getLogger(ConcurrentTestBase.class);
    public static final CountDownLatch startLatch = new CountDownLatch(1);;
    public static CountDownLatch endLatch;
    int perCount;
    int clientNum;
    private String rpcName;

    public ConcurrentTestBase(String rpc, String[] args) {
        if (args == null || args.length < 2) {
            throw new RuntimeException("must input 2 paramter:clientNum,perCount");
        }
        rpcName = rpc;
        clientNum = Integer.parseInt(args[0]);
        perCount = Integer.parseInt(args[1]);
        endLatch = new CountDownLatch(clientNum);
    }

    public abstract void exec(CountDownLatch startLatch, CountDownLatch endLatch);

    public int getPerCount() {
        return perCount;
    }

    public int getClientNum() {
        return clientNum;
    }

    public void start() {
        ExecutorService executor = Executors.newFixedThreadPool(clientNum,new DefaultThreadFactory());
        for (int j = 0; j < clientNum; j++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    exec(ConcurrentTestBase.startLatch, ConcurrentTestBase.endLatch);
                }
            });
        }


        try {


            startLatch.countDown();
            long start = System.currentTimeMillis();

            endLatch.await();

            long used = System.currentTimeMillis() - start;
            LOGGER.debug(rpcName + ":client num:" + clientNum + ",execute per client:"
                    + perCount + ",total execute:" + perCount * clientNum + ",total time:" + used
                    / 1000 + "s, tps:" + perCount * clientNum * 1000.0 / used);

            executor.shutdown();

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

    }



}
